package org.nicocube.airain.gwt.client;

import org.nicocube.airain.domain.client.character.GameCharacter;
import org.nicocube.airain.domain.client.character.ObservableGameCharacter;
import org.nicocube.airain.gwt.client.rpc.GCService;
import org.nicocube.airain.gwt.client.rpc.GCServiceAsync;
import org.nicocube.airain.gwt.client.ui.ActionSchedulerPanel;
import org.nicocube.airain.gwt.client.ui.ActivitiesLogPanel;
import org.nicocube.airain.gwt.client.ui.AirainMessager;
import org.nicocube.airain.gwt.client.ui.AttrAndSkillPanel;
import org.nicocube.airain.gwt.client.ui.ObserverLabel;
import org.nicocube.airain.gwt.client.ui.PossessionsPanel;

import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DecoratedPopupPanel;
import com.google.gwt.user.client.ui.DecoratedTabPanel;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Entry point class of Airain Web Game UI
 * 
 * @author nicocube
 * @version 0.1
 */
public class AirainWeb implements EntryPoint {

	/**
	 * The constants used in this Content Widget.
	 */
	/*
	 * public static interface AirainConstants extends Constants {
	 * 
	 * @DefaultStringValue(
	 * "Add rounded corners to any Widget using the Decorator Panel") String
	 * cwDecoratorPanelDescription();
	 * 
	 * @DefaultStringValue("Description:") String
	 * cwDecoratorPanelFormDescription();
	 * 
	 * @DefaultStringValue("Name:") String cwDecoratorPanelFormName();
	 * 
	 * @DefaultStringValue("Enter Search ConstraintCriteria") String
	 * cwDecoratorPanelFormTitle();
	 * 
	 * @DefaultStringValue("Decorator Panel") String cwDecoratorPanelName(); }
	 * 
	 * 
	 * private AirainConstants constants;
	 */
	/**
	 * The character we want to show on screen
	 */

	private GCServiceAsync gcSvc;

	private GameCharacter gc;

	private AirainMessager messenger;

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		/*
		 * We let gwt-log be the Log handler
		 */
		Log.setUncaughtExceptionHandler();
		DeferredCommand.addCommand(new Command() {
			public void execute() {
				init();
			}
		});
	}

	/**
	 * We initiate the messenger popup and load the GameCharacter
	 * Asynchronously, then launch the UI
	 */
	private void init() {
		DecoratedPopupPanel simplePopup = new DecoratedPopupPanel(false);
		simplePopup.setAnimationEnabled(true);
		simplePopup.hide();
		messenger = new AirainMessager(simplePopup);

		getMessager().show("Please wait while loading.");

		gcSvc = GWT.create(GCService.class);

		gcSvc.retrieveGameCharacter(new AsyncCallback<GameCharacter>() {
			public void onFailure(Throwable caught) {
				Log.error("Error :", caught);
				getMessager().show("Error while retrieving.");
			}

			public void onSuccess(GameCharacter result) {
				gc = new ObservableGameCharacter(result);
				getMessager().hide();
								
				launchUI();
				
			}
		});

//		DeferredCommand.addCommand(new IncrementalCommand() {
//			public boolean execute() {
//				now.incHour();
//				return true;
//			}
//		});

	}

	/**
	 * launch the UI component
	 */
	private void launchUI() {

		DecoratorPanel rootPanel = new DecoratorPanel();
		rootPanel.addStyleName("rootPanel");

		VerticalPanel vp = new VerticalPanel();

		DecoratorPanel decPanel = new DecoratorPanel();
		decPanel.addStyleName("airain-name-panel");

		HorizontalPanel hp = new HorizontalPanel();
		hp.setSpacing(10);

		Label l1 = new Label(gc.getName());
		l1.setWidth("300px");
		l1.setWordWrap(false);

		hp.add(l1);

		Label l2 = new ObserverLabel<ObservableGameCharacter>((ObservableGameCharacter)gc) {
			@Override
			public String render(ObservableGameCharacter publisher) {
				Log.debug("GameCharacter:\n"+publisher.toString());
				String res = gc.getBirthdate().getAge(publisher.getLivedate());
				Log.debug("render():"+res);
				return res;
			}
		};
		// l2.setWidth("400px");
		l2.setWordWrap(false);

		hp.add(l2);

		decPanel.add(hp);

		vp.add(decPanel);

		DecoratedTabPanel tp = new DecoratedTabPanel();

		tp.setWidth("400px");
		tp.getDeckPanel().setAnimationEnabled(true);

		AttrAndSkillPanel f1 = new AttrAndSkillPanel(this);
		PossessionsPanel f2 = new PossessionsPanel(this);
		ActionSchedulerPanel f3 = new ActionSchedulerPanel(this);
		ActivitiesLogPanel f4 = new ActivitiesLogPanel(this);

		f1.addTo(tp);
		f2.addTo(tp);
		f3.addTo(tp);
		f4.addTo(tp);

		tp.selectTab(0);

		vp.add(tp);

		rootPanel.add(vp);

		// Add it to the root panel.
		RootPanel.get().add(rootPanel);
		
		Timer t = new Timer() {
			public void run() {
				gcSvc.updateGameCharacter(gc.getLivedate(),new AsyncCallback<GameCharacter>() {
					//@Override
					public void onFailure(Throwable caught) {
						Log.error("Error :", caught);
						getMessager().show("Error while updating.");					
					}
					//@Override
					public void onSuccess(GameCharacter result) {
						Log.debug("Timer : updateGameCharacter.onSuccess");
						if (result != null) {
							gc.synchronise(result);
						}
					}
					
				});
			}
		};

		// Schedule the timer to run once in 5 seconds.
		t.scheduleRepeating(10000);

	}

	public GameCharacter getGc() {
		return gc;
	}

	public AirainMessager getMessager() {
		return messenger;
	}
}